/**
 * 
 */
package com.kth.subtranslator.driver;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.ws.rs.core.MultivaluedMap;

import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;

import com.kth.subtranslator.IBatchTranslateCallBack;
import com.kth.subtranslator.TranslateEngine;
import com.kth.subtranslator.TranslateEngine.Language;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.core.util.MultivaluedMapImpl;

/**
 * @author axddd
 *
 */
public class GoogleTranslateDriver extends AbstractTranslateDriver {

	private static final String googleTranslationService =
			"http://ajax.googleapis.com/ajax/services/language";
	private final Client client;

	private int textMaxSize = 4000;

	private final Map<Language, String> languageMapping = new HashMap<TranslateEngine.Language, String>();

	public GoogleTranslateDriver() {
		ClientConfig config = new DefaultClientConfig();
		this.client = Client.create(config);

		languageMapping.put(Language.ENGLISH, "en");
		languageMapping.put(Language.FRENCH, "fr");
	}

	/* (non-Javadoc)
	 * @see com.kth.subtranslator.ITranslateDriver#translate(java.lang.String, com.kth.subtranslator.TranslateEngine.Language, com.kth.subtranslator.TranslateEngine.Language)
	 */
	@Override
	public String translate(String text, Language fromLang, Language toLang) {
		if (text.length() > textMaxSize) {
			return translateBigString(text, fromLang, toLang);
		}
		return translateString(text, fromLang, toLang);
	}

	/* (non-Javadoc)
	 * @see com.kth.subtranslator.ITranslateDriver#translate(java.util.Collection, com.kth.subtranslator.TranslateEngine.Language, com.kth.subtranslator.TranslateEngine.Language)
	 */
	@Override
	public Collection<String> batchTranslate(Collection<String> text, Language fromLang, Language toLang, IBatchTranslateCallBack callBack) {
		//		List<String> translateStrings = new ArrayList<String>();
		//		for (Iterator<String> iterator = text.iterator(); iterator.hasNext();) {
		//			translateStrings.add( translateString(iterator.next(), fromLang, toLang) );
		//		}

		List<String> translatedTexts = new ArrayList<String>();

		StringBuilder textSb = new StringBuilder();
		for (String t : text) {
			textSb.append(t).append("<br>");
		}

		String translatedText;
		translatedText = translate(textSb.toString(), fromLang, toLang);
		String[] splitedText = translatedText.split("<br>");

		for (int i = 0; i < splitedText.length; i++) {
			translatedTexts.add( splitedText[i] );

		}

		return translatedTexts;
	}

	/* (non-Javadoc)
	 * @see com.kth.subtranslator.ITranslateDriver#getSupportedLanguage()
	 */
	@Override
	public Collection<Language> getSupportedLanguage() {
		return languageMapping.keySet();
	}

	private String translateString(String sourceString, Language sourceLanguage, Language targetLanguage) {
		WebResource r = this.client.resource(googleTranslationService);
		MultivaluedMap<String, String> params = new MultivaluedMapImpl();

		params.add("v", "1.0");
		params.add("q", sourceString); // string to translate
		params.add("langpair",
				languageToString(sourceLanguage)+"|"+ languageToString(targetLanguage) ); // translation pair: from language and to language

		String response =
				r.path("translate").post(String.class, params);
		return parseTranslation(response);
	}

	protected String translateBigString(String text, Language fromLang, Language toLang) {
		List<String> chunked = chunkString(text, textMaxSize);
//		Collection<String> translatedTexts = batchTranslate(chunked, fromLang, toLang);
		List<String> translateStrings = new ArrayList<String>();
		for (Iterator<String> iterator = chunked.iterator(); iterator.hasNext();) {
			translateStrings.add( translateString(iterator.next(), fromLang, toLang) );
		}
		StringBuilder sb = new StringBuilder();
		for (Iterator<String> iterator = translateStrings.iterator(); iterator.hasNext();) {
			sb.append( iterator.next() );
		}
		return sb.toString();
	}

	private String parseTranslation(String jsonTxt) {
		JSONObject json = (JSONObject) JSONSerializer.toJSON( jsonTxt );
		String statusCode = json.getString("responseStatus");
		System.out.println("staus code = " + statusCode);
		if (Integer.parseInt(statusCode) == 200) {
			JSONObject responseData = json.getJSONObject("responseData");
			String translatedContent = responseData.getString("translatedText");
			return translatedContent;
		}
		else {
			System.out.println("responseDetails = " + json.getString("responseDetails"));
			return json.getString("responseDetails");
		}
	}

	private String languageToString(Language lang) {
		return languageMapping.get(lang);
	}

	@Override
	public String getName() {
		return "Google translate Driver";
	}

	/* (non-Javadoc)
	 * @see com.kth.subtranslator.ITranslateDriver#stop()
	 */
	@Override
	public void stop() {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see com.kth.subtranslator.ITranslateDriver#getSupportedTargetLanguage(com.kth.subtranslator.TranslateEngine.Language)
	 */
	@Override
	public Collection<Language> getSupportedTargetLanguage(Language fromLang) {
		return getSupportedLanguage();
	}

}
